package com.pzr.soccer.uitl;

import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.function.BiFunction;

/**
 * @Author pzr
 * @date:2021-12-10-7:21
 * @Description:
 **/
@Slf4j
public class Comparer {
    public static final String Greater_Than=">";
    public static final String Greater_Equal_Than =">=";
    public static final String Less_Than ="<";
    public static final String Less_Equal_Than ="<=";
    public static final String Equal_Than ="=";
    public static final String Contains_Keyword ="contains";
    public static final String Date_Between ="date_between";
    public static final String Time_Between ="time_between";
    public static final String Time_Before ="time_before";
    public static final String Time_After ="time_after";
    public static final String Date_Before ="date_before";
    public static final String Date_After ="date_after";


    /**
     *
     * @param operator 比较符 >=  =  contains  between 等
     * @param left 表达式左边
     * @param right 表达式右边  如果@operator 是 between , 必须是一个包含开始和结束时间的collection
     *              e.g。 list.of("2012-01-01","2012-12-31")
     * @return 表达式是否正确
     */
    public static boolean compare(String operator,Object left,Object right){
        return   comparerMap().get(operator).apply(left,right);
    }


    private static Map<String, BiFunction<Object,Object,Boolean>> comparerMap(){
        Map<String, BiFunction<Object,Object,Boolean>> comparerMap=new HashMap<>();

        comparerMap.put(Greater_Than,(left,right)-> convertToNum(left)>convertToNum(right));
        comparerMap.put(Greater_Equal_Than,(left, right)-> convertToNum(left)>=convertToNum(right));
        comparerMap.put(Less_Equal_Than,(left, right)-> convertToNum(left)<=convertToNum(right));
        comparerMap.put(Less_Than,(left, right)-> convertToNum(left)<convertToNum(right));
        comparerMap.put(Equal_Than,(left, right)-> convertToNum(left)>=convertToNum(right));
        comparerMap.put(Contains_Keyword,(left, right)-> left.toString().contains(right.toString()));
        comparerMap.put(Time_Before,(left, right)-> convertToTime(left).isBefore(convertToTime(right)));
        comparerMap.put(Time_After,(left, right)-> convertToTime(left).isAfter(convertToTime(right)));
        comparerMap.put(Date_Before,(left, right)-> convertToDate(left).isBefore(convertToDate(right)));
        comparerMap.put(Date_After,(left, right)-> convertToDate(left).isAfter(convertToDate(right)));

        //right是一包含了开始和结束时间的list
        comparerMap.put(Date_Between,(left,right)->{
             if(right instanceof List||right instanceof Set){
                 List<Object> list= new ArrayList((Collection) right);
                 return (convertToDate(list.get(0)).isBefore(convertToDate(left))||convertToDate(list.get(0)).isEqual(convertToDate(left)))&&
                         (convertToDate(list.get(1)).isAfter(convertToDate(left))||convertToDate(list.get(1)).isEqual(convertToDate(left)));
             }else {
                 log.error("无效的日期时间区间："+right.toString());
             }
            return false;
        });

        //right是一包含了开始和结束时间的list
        comparerMap.put(Time_Between,(left,right)->{
            if(right instanceof List||right instanceof Set){
                List<Object> list= new ArrayList((Collection) right);
                return convertToTime(list.get(0)).isBefore(convertToTime(left))&&
                        convertToTime(list.get(1)).isAfter(convertToTime(left));
            }else {
                log.error("无效的日期时间区间："+right.toString());
            }
            return false;
        });
        return comparerMap;
    }



    private static int  convertToNum(Object o){
        try {
            return Integer.parseInt(o.toString());
        }catch (Exception e){
            log.error("无效的数字："+o);
            return 0;
        }
    }

    private static LocalDate convertToDate(Object o){
        try {
            return LocalDate.parse(o.toString());
        }catch (Exception e){
            log.error("无效的日期："+o);
            return LocalDate.parse("2999-12-31");
        }
    }

    private static LocalTime convertToTime(Object o){
        try {
            return LocalTime.parse(o.toString());
        }catch (Exception e){
            log.error("无效的时间或者格式不对(需要list或者set，如List.of(begin,end))："+o);
            return LocalTime.parse("00:00:00");
        }
    }

}
